package com.jk.vehicle.mini.intercept;

import com.jk.vehicle.mini.util.RedisUtil;
import com.jk.vehicle.mini.util.StringHelper;
import com.jk.vehicle.core.constants.TokenConstants;
import com.jk.vehicle.core.exception.LoginException;
import com.jk.vehicle.core.interceptor.BaseInterceptor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.List;
import java.util.regex.Pattern;

/**
 * 全局拦截器
 * @author zhangdongdong
 * @date 2019/7/7
 */
@Slf4j
public class SmartDashboardInterceptor extends BaseInterceptor {
	@Resource
	private RedisUtil redisUtil;

	/**
	 * 免登录接口地址
	 */
	private List<String> uncheckUrls = null;

	public SmartDashboardInterceptor(List<String> uncheckUrls) {
		this.uncheckUrls = uncheckUrls;
	}

	/**
	 * 进入controller层之前拦截请求
	 * @param request 请求
	 * @param response 响应
	 * @param o 参数
	 * @return 返回
	 */
	@Override
	public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object o) {
		String requestUri = request.getRequestURI();
		String requestMethod = request.getMethod();
		String token = request.getHeader(TokenConstants.TOKEN_HEADER);
		if ((StringUtils.isEmpty(token) || token.equals("undefined")) && !isContainsURI(requestUri, uncheckUrls)) {
			log.info("==========ignored because of uncheckUrls, request uri:{}", requestUri);
			return true;
		}

		// 根据是否有token判断该用户是否已登录
		if (StringUtils.isEmpty(token) || token.equals("undefined") || !redisUtil.exists(token)){
			throw new LoginException("当前用户未登录");
		}

		return true;
	}

	/**
	 * 当前uri 是否不需要拦截
	 *
	 * @param uri 请求地址
	 * @param list 免登录地址列表
	 * @return 校验结果
	 */
	private static boolean isContainsURI(String uri, List<String> list) {
		StringBuffer regEx;
		for (String url : list) {
			regEx = new StringBuffer(StringHelper.getUrlRegex(url));
			Pattern pattern = Pattern.compile(regEx.toString());
			if (pattern.matcher(uri).matches()) {
				return true;
			}
		}
		return false;
	}
}
